﻿using Chemistry.Models;
using Chemistry.Tools;
using GalaSoft.MvvmLight.Command;
using OPCAutomation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GLCommon;
using PORTS = System.IO.Ports;


namespace Chemistry.ViewModels
{
    public class ConfigViewModel:VmBase
    {
        #region 串口字段、属性
        private String name;
        private int baudRate = 9600;
        private int dataBit = 8;
        private StopBits stopBit = System.IO.Ports.StopBits.One;
        private Parity parity = Parity.None;
        private List<String> comNames;
        private List<int> baudRates;
        private List<int> dataBits;
        private List<string> models;
        private Dictionary<PORTS.StopBits, String> stopBits;
        private Dictionary<PORTS.Parity, String> parities;
        public SerialPort SerialPort { get; set; }
        public List<String> ComNames
        {
            get { return this.comNames; }
        }
        public List<int> BaudRates
        {
            get { return this.baudRates; }
        }
        public List<int> DataBits
        {
            get { return dataBits; }
        }
        public List<string> Models
        {
            get { return models;}
            set { this.models = value; }
        }
        public Dictionary<PORTS.StopBits, String> StopBits
        {
            get { return stopBits; }
        }
        public Dictionary<PORTS.Parity, String> Parities
        {
            get { return parities; }
        }

        private string _selectedModel;
        /// <summary>
        /// 选择模式
        /// </summary>
        public String SelectedModel
        {
            get { return _selectedModel; }
            set
            {
                this._selectedModel = value;
                RaisePropertyChanged("SelectedModel");
            }
        }
        public String Name
        {
            get { return name; }
            set
            {
                this.name = value;
                RaisePropertyChanged("Name");
            }
        }
        /// <summary>
        /// 波特率
        /// </summary>
        public int BaudRate
        {
            get { return this.baudRate; }
            set
            {
                this.baudRate = value;
                RaisePropertyChanged("BaudRate");
            }
        }
        /// <summary>
        /// 数据位
        /// </summary>
        public int DataBit
        {
            get { return this.dataBit; }
            set
            {
                this.dataBit = value;
                RaisePropertyChanged("DataBit");
            }
        }
        /// <summary>
        /// 停止位
        /// </summary>
        public PORTS.StopBits StopBit
        {
            get { return this.stopBit; }
            set
            {
                this.stopBit = value;
                RaisePropertyChanged("StopBit");
            }
        }
        /// <summary>
        /// 校验位
        /// </summary>
        public PORTS.Parity Parity
        {
            get { return this.parity; }
            set
            {
                this.parity = value;
                RaisePropertyChanged("Parity");
            }
        }



        #endregion

        #region OPC 配置
        private string _ip="127.0.0.1";
        public ConfigModel ConfigModel { get; set; }

        public List<string> OPCServers { get; set; }
        public string SelectedServer { get; set; }
        #endregion

        public RelayCommand SaveCommand { get; set; }
        public RelayCommand SelectPathCommand { get; set; }

        public ConfigViewModel()
        {
            SaveCommand = new RelayCommand(SaveExec);
            SelectPathCommand = new RelayCommand(SelectPathExec);
            InitSerialPort();
            InitOPC();
            InitConfigData();
            InitMessage();

            InitRunModel();
        }

        private void InitRunModel()
        {
            Models = Enum.GetNames(typeof (RunModel)).ToList();
            try
            {
                var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);               
                var configmodel=  config.AppSettings.Settings["Model"];
                SelectedModel = configmodel != null ? configmodel.Value : Models[0];

            }
            catch (Exception)
            {
                SelectedModel = Models[0];
            }
        }

        
        #region 初始化
        private void InitMessage()
        {


        }
        private void InitOPC()
        {
            OPCServers = new List<string>();
            OPCServer server = new OPCServer();
            string hostName = Dns.GetHostName();
            object servers = server.GetOPCServers();

            foreach (string item in (Array)servers)
            {
                OPCServers.Add(item);
            }
              
        }

        private void InitSerialPort()
        {
            comNames = new List<string>();
            PORTS.SerialPort.GetPortNames();
            foreach (String s in PORTS.SerialPort.GetPortNames())
            {
                comNames.Add(s);
            }
            baudRates = new List<int>() { 110, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 961200 };
            dataBits = new List<int>() { 5, 6, 7, 8 };
            stopBits = new Dictionary<PORTS.StopBits, string>();
            stopBits.Add(PORTS.StopBits.One, "1");
            stopBits.Add(PORTS.StopBits.OnePointFive, "1.5");
            stopBits.Add(PORTS.StopBits.Two, "2");

            parities = new Dictionary<PORTS.Parity, string>();
            parities.Add(PORTS.Parity.None, "无");
            parities.Add(PORTS.Parity.Odd, "奇校验");
            parities.Add(PORTS.Parity.Even, "偶校验");
            parities.Add(PORTS.Parity.Mark, "标记");
            parities.Add(PORTS.Parity.Space, "空格");
        }

      

        private void InitConfigData()
        {
            using (FileStream fs = new FileStream(Global.CONFIGDATA_PATH, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                try
                {
                    if (fs.Length > 0)
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        ConfigModel = (ConfigModel)formatter.Deserialize(fs);
                    }
                    else
                    {
                        ConfigModel = new ConfigModel()
                        {
                            Parity = PORTS.Parity.None,
                            BaudRate = 9600,
                            DataBit = 8,
                            IP = _ip,
                            StopBit = PORTS.StopBits.One,

                        };
                    }
                }
                catch (Exception ex)
                {
                    LogTool.WriteErrorLog(ex);
                    ConfigModel = new ConfigModel()
                    {
                        Parity = PORTS.Parity.None,
                        BaudRate = 9600,
                        DataBit = 8,
                        IP = _ip,
                        StopBit = PORTS.StopBits.One,

                    };
                }
            }
        } 
        #endregion

        #region 命令方法
        private void SelectPathExec()
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.Description = @"请选择打印文件保存路径";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                this.ConfigModel.PrintPath = dialog.SelectedPath;
            }
        }

        private void SaveExec()
        {
            try
            {
                using (FileStream fs = new FileStream(Global.CONFIGDATA_PATH, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write))
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(fs, ConfigModel);
                }

                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                config.AppSettings.Settings["Model"].Value = this.SelectedModel;
                config.Save();
                Global.RunModel = (RunModel) Enum.Parse(typeof (RunModel), SelectedModel);
                Send(MessageToken.SaveConfigOver);
            }
            catch (Exception ex)
            {
                AppendExecptionAsync(ex);
                Send<string>(ex.Message,MessageToken.SaveConfigError);
            }
        } 
        #endregion


    }
}
